﻿using System.Collections.Generic;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using System;

namespace StockholmsStad.Data.Interfaces
{
    /// <summary>
    /// Hantering av ärendens
    /// </summary>
    public interface ITicketAgent
    {
        /// <summary>
        /// Skapa ett nytt ärende för ett par med ceremonival utav en administratör. 
        /// </summary>
        /// <param name="context">Datakontexten (<see cref="IDataContext"/>) som transaktionen använder.</param>
        /// <param name="couple">Paret (<see cref="Couple"/>) som ska läggas till ärendet.</param>
        /// <param name="ceremony">Ceremonyinformation (<see cref="Ceremony"/>) som ska läggas till ärendet.</param>
        /// <returns>Idnumret på det skapade ärendet</returns>
        int CreateTicket(IDataContext context, Couple couple, Ceremony ceremony);

        /// <summary>
        /// Skapa ett nytt ärende för ett par med ceremonival för en viss inloggad användare. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="couple"></param>
        /// <param name="ceremony"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        int CreateTicket(IDataContext context, Couple couple, Ceremony ceremony, int userId);

        /// <summary>
        /// Hämtar ett givet ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="username">Ärendets id värde</param>
        /// <returns>Det aktuella ärendet. </returns>
        int GetTicketId(IDataContext context, string username);

        /// <summary>
        /// Hämtar ett givet ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId">Ärendets id värde</param>
        /// <returns>Det aktuella ärendet. </returns>
        Ticket GetTicket(IDataContext context, int ticketId);

        /// <summary>
        /// Hämtar bokningsnumret för ett visst ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId">Ärendets id värde</param>
        /// <returns>Bokningsnumret</returns>
        int? GetBookingId(IDataContext context, int ticketId);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="partOfName"></param>
        /// <param name="partOfBirthday"></param>
        /// <param name="ticketStatus"></param>
        /// <returns></returns>
        List<CouplesSummaryItem> GetTickets(IDataContext context, string partOfName, string partOfBirthday,
                                            TicketStatusType ticketStatus);

        /// <summary>
        /// Uppdaterar ett befintligt par
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId">Ärendenumret på det ärende som ska uppdateras</param>
        /// <param name="couple">Paret som ska uppdateras</param>
        void UpdateCouple(IDataContext context, int ticketId, Couple couple);

        /// <summary>
        /// Uppdaterar statusen på ett ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId">Ärendets id-nr. </param>
        /// <param name="ticketStatusType">Aktuell status på ärendet. </param>
        void UpdateTicketStatus(IDataContext context, int ticketId, TicketStatusType ticketStatusType);

        /// <summary>
        /// Uppdaterar ett befintligt ärende
        /// </summary>
        /// <param name="couple">Paret som ska uppdateras</param>
        /// <param name="ceremony">Ceremoni information som ska uppdateras</param>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="ticketId">Ärendenumret på det ärende som ska uppdateras</param>
        /// <param name="username"></param>
        void UpdateTicket(IDataContext context, int ticketId, Couple couple, Ceremony ceremony, string username);

        /// <summary>
        /// Tar fram ticketen för användaren 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i</param>
        /// <param name="user"></param>
        /// <returns></returns>
        Ticket GetTicket(IDataContext context, User user);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ticketId"></param>
        /// <returns></returns>
        Couple GetCouple(IDataContext context, int ticketId);

        /// <summary>
        /// Skapar en notic
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketId">Det ärende som historiken ska kopplas till. </param>
        /// <param name="message">Beskrivande meddelande av historiken som ska läggas till.</param>
        /// <param name="user">Vilken användare som har utfört aktionen. </param>
        void InsertNotice(IDataContext context, int ticketId, string message, string user);

        /// <summary>
        /// Lägger till historik till ärendet. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketId">Det ärende som historiken ska kopplas till. </param>
        /// <param name="message">Beskrivande meddelande av historiken som ska läggas till.</param>
        /// <param name="user">Vilken användare som har utfört aktionen. </param>
        /// <param name="isPublic">Indikerar ifall paret också ska kunna se informationen. </param>
        void InsertHistory(IDataContext context, int? ticketId, string message, string user, bool isPublic);

        /// <summary>
        /// Hämtar historik för ett visst ärende. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketId">Det ärende som historiken ska kopplas till. </param>
        /// <param name="isPublic">Om sann hämtas endast de publika ärendena, om falsk hämtas alla.</param>
        /// <returns>En lista med all historik som rör ett visst ärende. </returns>
        List<History> GetHistoryItems(IDataContext context, int ticketId, bool isPublic);

        /// <summary>
        /// Notisen markeras som läst och visas därmed inte längre i att-göra listan
        /// </summary>
        /// <param name="context"></param>
        /// <param name="historyId"></param>
        void InactivateNotice(IDataContext context, int historyId);

        /// <summary>
        /// Hämtar notiser för alla ärenden. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <returns>En lista med all historik som rör ett visst ärende. </returns>
        List<History> GetNotices(IDataContext context);

        /// <summary>
        /// Hämtar all ceremoniinformation för ett ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketId">Det ärende som historiken ska kopplas till. </param>
        /// <returns>Ceremoniinformationen (<see cref="Ceremony"/>).</returns>
        Ceremony GetCeremony(IDataContext context, int ticketId);

        /// <summary>
        /// Hämtar extra information om ett ärende. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketId">Det ärende som historiken ska kopplas till. </param>
        /// <returns>Övrig information om ärendet. </returns>
        TicketInformation GetTicketInformation(IDataContext context, int ticketId);

        /// <summary>
        /// Läggar till extra information till ett ärende
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketInformation">Det information som ska läggas till ärendet (<see cref="TicketInformation"/>). </param>
        /// <returns>Id:t på den tillagda informationen. </returns>
        int AddTicketInformation(IDataContext context, TicketInformation ticketInformation);

        /// <summary>
        /// Uppdaterar befintlig information. 
        /// </summary>
        /// <param name="context">Det databascontext som operationen köra i.</param>
        /// <param name="ticketInformation">Det information som ska uppdateras (<see cref="TicketInformation"/>). </param>
        void UpdateTicketInformation(IDataContext context, TicketInformation ticketInformation);

        /// <summary>
        /// Hämtar icke-lediga tidsblock som en lista med start-slut-datum (för kalender som 
        /// endast tar "utblockade" datum. 
        /// </summary>
        /// <param name="context"></param>
        /// <returns>En lista med </returns>
        List<DateRange> GetNonAvailableDates(IDataContext context);
    
        /// <summary>
        /// Hämtar icke fullbokade tidsblock som en lista med start-slut-datum (för kalender som 
        /// endast tar "utblockade" datum. 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        List<DateRange> GetNonFullyBookedDates(IDataContext context);

        /// <summary>
        /// Skicka registreringsmail till kunden
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        /// <param name="userName">Mottagaren av mailet och användarnamnet på inloggningen. </param>
        /// <param name="password">Den registrerade användarens lösenord. </param>
        /// <param name="fullName">Det fullständiga namnet på kontaktpersonen. </param>
        void SendRegistrationMail(IDataContext context, string userName, string password, string fullName);

        /// <summary>
        /// Skicka registreringsmail till kunden
        /// </summary>
        ///<param name="context">Det databascontext som operationen kör i</param>
        ///<param name="person">Vilken person som ska ha uppgifterna</param>
        ///<param name="userName"></param>
        ///<param name="password"></param>
        void SendRegistrationMail(IDataContext context, PersonDetails person, string userName, string password);

        /// <summary>
        /// Skicka registreringsmail till windows-klient användaren. 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="password"></param>
        void SendRegistrationMail(IDataContext context, ParvisUser user, string password);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        void SendRegistrationInParvisMail(IDataContext context, Runtime.Serialization.DataContract.ParvisUser user);
    }
}